package com.cn.task;

import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import org.springframework.beans.factory.NoSuchBeanDefinitionException;

import com.cn.bean.SimpleMap;
import com.cn.dao.JdbcDao;
import com.cn.dao.RowSet;
import com.cn.dao.SqlParam;
import com.cn.exception.MyException;
import com.cn.task.beans.TaskConfigBean;
import com.cn.task.timer.IScheduleIterator;
import com.cn.task.timer.SchedulerTask;
import com.cn.threadpool.MyThreadPool;
import com.cn.threadpool.MyThreadPoolProxy;
import com.cn.xc.utils.BeanUtil;
import com.cn.xc.utils.StringUtil;


/**
 * 
 * @author Leezy Description ：
 * 
 */
public abstract class BaseTask extends SchedulerTask {

	protected boolean isRunning = false;
	protected String taskCode;
	protected String poolName = null;
	protected TaskConfigBean taskConfig = new TaskConfigBean();
	protected JdbcDao jdbcDao;
	protected ITaskLogicService service;

	protected AtomicIntSeq fileSeq = new AtomicIntSeq(99999999);

	public boolean isRunning() {
		return isRunning;
	}

	public String getTaskCode() {
		return taskCode;
	}

	public void setTaskCode(String taskCode) {
		this.taskCode = taskCode;
	}

	public TaskConfigBean getTaskConfig() {
		return taskConfig;
	}

	public void setTaskConfig(TaskConfigBean taskConfig) {
		this.taskConfig = taskConfig;
	}

	// System Setting
	public void setPoolName(String poolName) {
		this.poolName = poolName;
	}

	public void setJdbcDao(JdbcDao jdbcDao) {
		this.jdbcDao = jdbcDao;
	}

	public void setService(ITaskLogicService service) {
		this.service = service;
	}

	@SuppressWarnings("unchecked")
	public void loadTaskConf() {

		System.out.print("TimerTask init begin..." + taskCode + "\n");

		if (StringUtil.isEmpty(taskCode)) {
			logger.error("The Task " + taskCode
					+ ":运行异常! Spring注入taskCode配置为空!");
			throw new MyException("任务缺少配置，Spring注入taskCode配置为空!");
		}

		try {
			SqlParam sqlParam = new SqlParam();
			sqlParam.addParam("taskCode", taskCode);
			sqlParam.addSql("select PARAM_CODE, PARAM_VALUE from TB_IC_TASK_CONF where STATE = 'S0A' and TASK_CODE = :taskCode");
			RowSet rs = jdbcDao.query(sqlParam);
			while (rs.next()) {
				this.saveToBean(rs, taskConfig);
			}
		} catch (Exception e) {
			logger.error("The Task " + taskCode
					+ ":read config information error!", e);
			throw new MyException("读取任务配置数据异常!" + e.getMessage());
		}

		setTaskName(taskConfig.getTaskName());
		setIteratorParam(taskConfig.getIteratorParam());
		setPoolName(taskConfig.getPoolName());

		try {
			setIteratorClass((Class<IScheduleIterator>) Class.forName(taskConfig.getIteratorClass()));
		} catch (ClassNotFoundException e) {
			logger.error("The Task " + taskCode + ":找不到对应配置定时类"
					+ taskConfig.getIteratorClass());
			throw new MyException("读取任务配置数据查询语句异常!" + e.getMessage());
		} catch (Throwable t) {
			logger.error("The Task " + taskCode + ":设置任务定时类失败" + taskConfig.getIteratorClass());
			throw new MyException( "设置定时任务类型异常!" + t.getMessage());
		} finally {

		}

		System.out.print("TimerTask init end..." + taskCode + "\n");
	}

	@Override
	public void run() {
		if (isRunning) {
			return;
		}
	}

	protected Object getFuture(Future<Object> future) {
		try {
			return future.get();
		} catch (InterruptedException e) {
			// 服务请求中断
			throw new MyException("", e, "poolName", poolName);
		} catch (ExecutionException e) {
			Throwable t = e.getCause();
			if (t != null) {
				if (t instanceof NoSuchBeanDefinitionException) {
					NoSuchBeanDefinitionException e1 = (NoSuchBeanDefinitionException) t;
					throw new MyException("",e1, poolName,"spring尚未注入的beanName：" + e1.getBeanName());
				} else if (t instanceof MyException) {
					throw (MyException) t;
				}
				throw new MyException("", t, "poolName", poolName, "errMsg", t.getMessage());
			}
			throw new MyException("", e,"poolName", poolName, "errMsg", e.getMessage());
		}
	}

	/**
	 * 异步执行任务
	 * 
	 * @param map
	 */
	@SuppressWarnings("unchecked")
	protected Future<Object> asyncDoTask(final SimpleMap param) {
		// 获取线程池
		MyThreadPool threadPool = MyThreadPoolProxy.getThreadPool(poolName);
		if (threadPool == null) {
			
			doTask(param);
			logger.warn("The Task " + param.getString("taskCode")
					+ "单线程生成的文件，暂无处理！");
			return null;
		} else {
			// 提交给线程池处理
			return (Future<Object>) threadPool.submit(new Callable<Object>() {
				public Object call() throws Exception {
					// 调用具体实现类中的execute()方法实现具体任务在线程池中运行
					return doTask(param);
				}
			});
		}
	}

	@SuppressWarnings("unchecked")
	protected Future<Object> asyncDoTask(final SimpleMap param,
			boolean skipNoThread) {

		// 获取线程池
		MyThreadPool threadPool = MyThreadPoolProxy.getThreadPool(poolName);
		if (threadPool == null) {
			if (skipNoThread) {
				logger.warn("The Task " + param.getString("taskCode") + ":"
						+ param.getString("cityId") + "处理申请子系统线程失败，跳过处理！");
				return null;
			} else {
				doTask(param);
				logger.warn("The Task " + param.getString("taskCode")
						+ "单线程事务处理的文件，暂无处理！");
				return null;
			}
		} else {
			// 提交给线程池处理
			return (Future<Object>) threadPool.submit(new Callable<Object>() {
				public Object call() throws Exception {
					// 调用具体实现类中的execute()方法实现具体任务在线程池中运行
					return doTask(param);
				}
			});
		}
	}

	/**
	 * 
	 * @param taskObject
	 * @return Description ：同步执行任务
	 * 
	 */

	protected Object syncDoTask(Object... args) {

		return doTask(args);

	}

	protected Object doTask(Object... args) {

		return service.run(args);
	}

	/**
	 * 将数据库配置数据注入Bean
	 * 
	 * @param rs
	 * @param bean
	 */
	protected void saveToBean(RowSet rs, Object bean) {
		PropertyDescriptor[] pds = BeanUtil.getPropertyDescriptors(bean
				.getClass());
		if (pds == null || pds.length <= 0) {
			return;
		}

		String colName = rs.getString(1);
		Class<?> cls = null;
		for (PropertyDescriptor pd : pds) {
			cls = pd.getPropertyType();
			if (cls == Class.class || SimpleMap.class.isAssignableFrom(cls)) {
				continue;
			}

			if (pd.getName().equals(colName)) {
				if (cls == String.class) {// String类型
					BeanUtil.setPropertyValue(bean, pd, rs.getString(2));
				} else if (cls == Long.class || cls == long.class) {// long类型
					BeanUtil.setPropertyValue(bean, pd, rs.getLong(2));
				} else if (Date.class.isAssignableFrom(cls)) {// 日期类型
					BeanUtil.setPropertyValue(bean, pd, rs.getDate(2));
				} else if (List.class.isAssignableFrom(cls)) {// List类型
					String paramValue = rs.getString(2);
					if (StringUtil.isNotEmpty(paramValue)) {
						String sep = ",";
						StringTokenizer token = new StringTokenizer(paramValue,
								sep);
						int count = token.countTokens();

						if (count > 0) {
							List<String> tmpList = new ArrayList<String>();
							while (token.hasMoreTokens()) {
								tmpList.add(token.nextToken());
							}
							BeanUtil.setPropertyValue(bean, pd, tmpList);
						}
					}
				}
			}
		}
	}

}
